﻿using CoachingOrganizer.Logic.Models.Common;
using CoachingOrganizer.Logic.Models.Tools;
using CoachingOrganizer.Logic.Models.Tools.EmotionsPack;
using CoachingOrganizer.Logic.Models.Tools.MoneyCalculation;
using CoachingOrganizer.Logic.Models.Tools.MoodLevel;
using CoachingOrganizer.Toolkit.Collections.Helpers;
using CoachingOrganizer.Toolkit.Events;
using CoachingOrganizer.WinPhone.UITools;
using CoachingOrganizer.WinPhone.ViewModels.Tools;
using CoachingOrganizer.WinPhone.ViewModels.Tools.EmotionsPack;
using CoachingOrganizer.WinPhone.ViewModels.Tools.MoneyCalculation;
using CoachingOrganizer.WinPhone.ViewModels.Tools.MoodLevel;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Input;
using Windows.ApplicationModel.Resources;
using Windows.UI.Popups;

namespace CoachingOrganizer.WinPhone.ViewModels
{
    public class GoalViewModel : ViewModelBase
    {
        private readonly GoalModel _model;
        private readonly string[] _toolsList;
        private int _selectedToolIndex;
        private int _currentTabIndex;
        private ObservableCollection<ToolViewModelBase> _tools;

        public int SelectedToolIndex
        {
            get { return _selectedToolIndex; }
            set { _selectedToolIndex = value; }
        }

        public int CurrentTabIndex
        {
            get { return _currentTabIndex; }
            set
            {
                if (_currentTabIndex != value)
                {
                    _currentTabIndex = value;
                    OnPropertyChanged(() => PageTitle);
                }
            }
        }

        public string PageTitle
        {
            get { return GetPageTitle(_currentTabIndex); }
        }

        public string[] ToolsList
        {
            get { return _toolsList; }
        }

        public ObservableCollection<ToolViewModelBase> Tools
        {
            get { return _tools; }
        }

        public string Title
        {
            get { return _model.Title; }
            set { _model.Title = value; }
        }

        public string Description
        {
            get { return _model.Description; }
            set { _model.Description = value; }
        }

        public ICommand GoDetailsCommand
        {
            get { return GetCommand(() => GoDetailsCommand, () => UIHelper.GoToPage(this, typeof(CoachingOrganizer.WinPhone.Pages.GoalPage))); }
        }

        public ICommand SaveCommand
        {
            get { return GetCommand(() => SaveCommand, () => Save()); }
        }

        public ICommand RemoveCommand
        {
            get { return GetCommand(() => RemoveCommand, () => Remove()); }
        }

        public ICommand AddNewToolCommand
        {
            get { return GetCommand(() => AddNewToolCommand, () => AddNewTool()); }
        }

        public GoalViewModel(GoalModel model)
        {
            _model = model;
            _toolsList = ResourceLoader.GetForCurrentView().GetString("ToolsList").Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
            _model.ToolsChanged += Model_ToolsChanged;
            _model.ToolsCollectionChanged += Model_ToolsCollectionChanged;
            InitModel();
        }

        private async void AddNewTool()
        {
            ActionResult addResult = ActionResult.ValidResult;
            switch (_selectedToolIndex)
            {
                case 0:
                    addResult = await _model.AddNewMoodLevel();
                    break;
                case 1:
                    addResult = await _model.AddNewEmotionsPack();
                    break;
                case 2:
                    addResult = await _model.AddNewMoneyCalculation();
                    break;
            }
            if (!addResult.IsValid)
                await UIHelper.ShowErrorMessageAsync("");
        }

        private async void Save()
        {
            ActionResult result = await _model.Save();
            if (!result.IsValid)
                await UIHelper.ShowErrorMessageAsync("");
        }

        private async void Remove()
        {
            ActionResult result = await _model.Remove();
            if (!result.IsValid)
                await UIHelper.ShowErrorMessageAsync("");
        }

        private async void InitModel()
        {
            using (CancellationTokenSource cancellation = new CancellationTokenSource())
                await _model.LoadToolsAsync(cancellation.Token);
        }

        private async void NotifyLoadFailed()
        {
            MessageDialog dialog = new MessageDialog("");
            await dialog.ShowAsync();
        }

        private string GetPageTitle(int currentTabIndex)
        {
            switch (currentTabIndex)
            {
                case 0:
                    return ResourceLoader.GetForCurrentView().GetString("Common");
                case 1:
                    return ResourceLoader.GetForCurrentView().GetString("Supply");
                default:
                    break;
            }
            throw new NotImplementedException();
        }

        private void Model_ToolsChanged(object sender, EventArgs e)
        {
            IEnumerable<ToolModelBase> tools = _model.Tools;
            BeginInvokeInUIThread(() =>
            {
                _tools = tools == null ? null : new ObservableCollection<ToolViewModelBase>(tools.Select(m => CreateToolViewModel(m)));
                OnPropertyChanged(() => Tools);
            });
        }

        private void Model_ToolsCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            BeginInvokeInUIThread(() => ObservableCollectionHelper.ApplyChangesByNumbers<ToolModelBase, ToolViewModelBase>(e, _tools, m => CreateToolViewModel(m)));
        }

        private static ToolViewModelBase CreateToolViewModel(ToolModelBase model)
        {
            if (model is MoodLevelModel)
                return new MoodLevelViewModel((MoodLevelModel)model);
            if (model is EmotionsPackModel)
                return new EmotionsPackViewModel((EmotionsPackModel)model);
            if (model is MoneyCalculationModel)
                return new MoneyCalculationViewModel((MoneyCalculationModel)model);
            throw new NotImplementedException();
        }
    }
}
